#pragma once

#include <string>

#include "Http_agre.hpp"
#include "common.hpp"
#include "Logger.hpp"
#include "session.hpp"
#include "user.hpp"

using namespace LogMudule;

using namespace std;

void Login(const string &data, const HttpRequest &requ, HttpResponse &resp) // 登录
{
    LOG(LogLevel::DEBUG) << "开始登录服务,data: " << data;

    // 解析用户传递的数据
    string username;
    string password;

    string left, right;

    Partition(data, "&", left, right);

    string tmp;
    Partition(left, "=", tmp, username);

    Partition(right, "=", tmp, password);

    string tmp_url;

    // 判断该用户是否注册
    if (!guser_table.isExistence_Name(username))
    {
        LOG(LogLevel::DEBUG) << "登录失败，用户不存在 " << username;

        // 设置url
        tmp_url = "/login.html"; // 返回登录页面
    }
    else
    {
        uint64_t id = guser_table.NameToId(username);
        // 判断密码是否正确
        if (guser_table.isPasswordCorrect(id, password))
        {
            // 申请session_id
            uint64_t sid = gsession_table.GetSession();

            // 设置登录状态
            guser_table.SetisLogin(id, true);

            // 创建session
            Session session(id, sid, true);

            gsession_table.AddSession(id, session);

            // 构建登录成功的页面--假设登录成功就重定向到首页

            // 设置Cookie
            resp["Set-Cookie"] = "session_id=" + to_string(sid);

            resp["Location"] = "/"; // 重定向到首页
            // 设置HTTP版本
            resp.SetVersion(requ.version());

            // 设置状态码和状态码描述
            resp.SetStatusCode(302);
            resp.SetStatusCodeDescription("Found");

            return;
        }
        else // 密码不正确
        {
            LOG(LogLevel::DEBUG) << "登录失败，密码错误 " << username;

            tmp_url = "/login.html"; // 返回登录页面
        }
    }

    // 添加web根目录
    string url = defalut_web_root + tmp_url;

    // 设置HTTP版本
    resp.SetVersion(requ.version());

    // 打开资源文件
    ifstream ifs(url, ios::in);

    // 设置状态码和状态码描述
    resp.SetStatusCode(200);
    resp.SetStatusCodeDescription("OK");

    // 读取资源目录对应的首页文件
    string page;
    string line;
    while (getline(ifs, line))
    {
        page += (line + "\r\n");
    }
    // 设置响应报头
    resp["Content-Type"] = "html";
    resp["Content-Lenth"] = to_string(page.size());

    // 设置响应正文
    resp.SetBody(page);

    ifs.close();
}

void Register(const string &data, const HttpRequest &requ, HttpResponse &resp)
{
    LOG(LogLevel::DEBUG) << "开始注册服务,data: " << data;

    // 解析用户传递的数据
    string username;
    string password;

    string left, right;

    Partition(data, "&", left, right);

    string tmp;
    Partition(left, "=", tmp, username);

    Partition(right, "=", tmp, password);

    string tmp_url;

    // 判断该用户是否注册
    if (guser_table.isExistence_Name(username))
    {
        LOG(LogLevel::DEBUG) << "注册失败，用户已经存在 " << data;

        tmp_url = "/register.html"; // 到注册页面
    }
    else
    {
        // 申请user_id
        guser_id_mutex.lock();
        uint64_t id = guser_id++;
        guser_id_mutex.unlock();

        User user(id, username, password);
        // 注册新用户
        guser_table.AddUser(id, user);

        // 构建登录成功的页面--假设登录成功就重定向到  登录页面
        resp["Location"] = "/login.html"; // 重定向到登录页面
        // 设置HTTP版本
        resp.SetVersion(requ.version());

        // 设置状态码和状态码描述
        resp.SetStatusCode(302);
        resp.SetStatusCodeDescription("Found");

        return;
    }

    // 添加web根目录
    string url = defalut_web_root + tmp_url;

    // 设置HTTP版本
    resp.SetVersion(requ.version());

    // 打开资源文件
    ifstream ifs(url, ios::in);

    // 设置状态码和状态码描述
    resp.SetStatusCode(200);
    resp.SetStatusCodeDescription("OK");

    // 读取资源目录对应的首页文件
    string page;
    string line;
    while (getline(ifs, line))
    {
        page += (line + "\r\n");
    }
    // 设置响应报头
    resp["Content-Type"] = "html";
    resp["Content-Lenth"] = to_string(page.size());

    // 设置响应正文
    resp.SetBody(page);

    ifs.close();
}
